<template>
  <a-upload
    @beforeUpload="beforeUpload"
    :custom-request="customRequest"
    :accept="fileTypeList.join(',')"
    :listType="listType"
    :limit="limit"
    v-bind="args ? { ...args } : null"
    :draggable="draggable"
    :show-remove-button="isShowRemove"
    v-model:fileList="uploadList"
    :disabled="disabled"
    multiple
  >
    <template #extra-button="{ fileItem }" v-if="listType === 'text'">
      <a-space style="margin-left: 10px">
        <a-link @click="preview(fileItem.url)">预览</a-link>
        <a-link @click="preview(fileItem.url)">下载</a-link>
      </a-space>
    </template>
  </a-upload>
</template>

<script setup lang="ts">
import {
  reactive,
  onMounted,
  ref,
  nextTick,
  computed,
  watchEffect,
  watch
} from 'vue';
import { FileUpload } from '@/utils/upload';
import { Message } from '@arco-design/web-vue';
import { cloneDeep } from 'lodash';
import { ajaxService } from '@/utils/request';

export interface TFileItem {
  id?: number;
  fileUrl: string;
  fileName?: string;
  uid?: string;
  sourceAddr?: string;
}

const props = withDefaults(
  defineProps<{
    fileList: TFileItem[];
    fileTypeList?: string[];
    maxSize?: number;
    limit?: number;
    draggable?: boolean;
    isShowRemove?: boolean;
    args?: any; // 对象，放置a-upload的剩余属性
    disabled?: boolean;
    listType?: 'picture' | 'text' | 'picture-card';
  }>(),
  {
    fileTypeList: () => [],
    listType: 'text',
    limit: 1,
    maxSize: 10 * 1024 * 1024,
    isShowRemove: true
  }
);

const uploadList = ref<any[]>([]);
let refresh = () => {
  uploadList.value = [];
};
defineExpose({ refresh });

const setUploadList = () => {
  const list = cloneDeep(uploadList.value);
  props.fileList.forEach((item) => {
    const { id, fileUrl, fileName, uid, sourceAddr } = item;
    if (
      !list.some(
        (upload: any) =>
          uid === upload.uid ||
          fileUrl === upload.url ||
          fileUrl === upload?.response?.fileUrl
      )
    ) {
      uploadList.value.push({
        id,
        name: fileName,
        status: 'done',
        url: fileUrl,
        response: { fileUrl, fileName, sourceAddr }
      });
    }
  });
};
let preview = async (url: string) => {
  const res = await ajaxService({
    url,
    method: 'get',
    responseType: 'blob',
    baseURL: ''
  });
  const file = new Blob([res], { type: 'application/pdf' });
  const changeUrl = window.webkitURL.createObjectURL(file);
  window.open(changeUrl);
};
watch(
  () => props.fileList,
  () => setUploadList()
);
setUploadList();
const emit = defineEmits(['update:fileList', 'beforeRemove']);
watch(
  () => uploadList.value,
  () => {
    nextTick(() => {
      uploadList.value.forEach((item) => {
        item.url = item.response?.fileUrl;
      });
      emit(
        'update:fileList',
        uploadList.value
          .filter(({ status }) => status === 'done')
          .map((item: any) => {
            return {
              id: item.id,
              uid: item.uid,
              fileUrl: item.response?.fileUrl,
              fileName: item.response?.fileName,
              sourceAddr: item.response?.sourceAddr
            };
          })
      );
    });
  }
);
// 上传前校验
const beforeUpload = async (file: File) => {
  const { maxSize, fileTypeList } = props;
  if (maxSize && file.size > maxSize) {
    Message.warning(`文件过大,不可超过${(maxSize / 1048576).toFixed(2)}M`);
    return Promise.reject();
  }
  const fileType = file.name.slice(file.name.lastIndexOf('.') + 1);
  const fileName = file.name.slice(0, file.name.lastIndexOf('.'));
  // if (fileTypeList.length && !fileTypeList.includes(fileType)) {
  //   Message.warning(`${fileName}文件类型错误`);
  //   return Promise.reject();
  // }
  if (fileTypeList.length) {
    const lowercaseFileTypeList = fileTypeList.map((type) =>
      type.toLowerCase()
    );
    const lowercaseFileType = fileType.toLowerCase();

    if (!lowercaseFileTypeList.includes(lowercaseFileType)) {
      Message.warning(`${fileName}文件类型错误`);
      return Promise.reject();
    }
  }
  return Promise.resolve(file);
};
const customRequest = (option: any) => {
  const { onError, onSuccess, fileItem } = option;
  const formData = new FormData();
  formData.append('data', fileItem.file);
  FileUpload(formData)
    .then((res: any) => {
      onSuccess({
        fileUrl: res.data.data.addr,
        fileName: fileItem.name,
        sourceAddr: res.data.data.sourceAddr,
        url: res.data.data.addr
      });
    })
    .catch((err) => onError(err));
  return {
    abort: () => {
      //
    }
  };
};
</script>

<style scoped></style>
